/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.game.editor;

import com.serponix.game.Mapa;
import com.serponix.game.MessagePanel;
import com.serponix.gui.WindowInterface;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Model pro editor map.
 * Obsahuje aktuálně kreslenou mapu a metody pro její kreslení, mazání, uložení a načtení.
 * Model obsahuje i View pro vykreslování.
 *
 * @author Daniel Vala
 */
public class ModelEditor extends JPanel {

	private Mapa mapa;
	private int sirkaHernihoPanelu;
	private int vyskaHernihoPanelu;
	private WindowInterface okno;

	public ModelEditor(WindowInterface okno, MessagePanel panelZprav) {
		this.okno = okno;
		mapa = new Mapa();
		sirkaHernihoPanelu = 1099;
		vyskaHernihoPanelu = 599;
		panelZprav.addMessage(String.format("Pro návrat do menu stisknite ESCAPE"));
		panelZprav.addMessage(String.format("Pro smazání mapy stisknite DELETE"));
		panelZprav.addMessage(String.format("Pro uložení mapy stisknite S"));
		panelZprav.addMessage(String.format("Pro načtení mapy stisknite L"));
	}

	public int getSirka() {
		return sirkaHernihoPanelu;
	}

	public int getVyska() {
		return vyskaHernihoPanelu;
	}

	/**
	 * Ukončí editor map a vrátí se zpět do menu.
	 */
	public void ukonciEditor() {
		okno.displayMenu();
	}

	/**
	 * Přidá stěnu mapy (zeď) do celé mapy.
	 * Zeď zarovná do desítkové mřížky.
	 * Nelze přidat zeď mimo herní plochu.
	 *
	 * @param x X souřadnice zdi.
	 * @param y Y souřadnice zdi.
	 */
	public void pridejStenuMapy(int x, int y) {
		x = (int) (x / (getWidth() / new Double(getSirka()))) / 10;
		y = (int) (y / (getHeight() / new Double(getVyska()))) / 10;
		// ošetření, aby se nedalo kreslit mimo herní plochu
		if (x >= 0 && x <= sirkaHernihoPanelu && y >= 0 && y <= vyskaHernihoPanelu) {
			mapa.pridejZed(x, y);
		}
	}

	/**
	 * Vymaže zeď zadaných souřadnicích.
	 *
	 * @param x Souřadnice zdi X.
	 * @param y Souřadnice zdi Y.
	 */
	public void vymazStenuMapy(int x, int y) {
		x = (int) (x / (getWidth() / new Double(getSirka()))) / 10;
		y = (int) (y / (getHeight() / new Double(getVyska()))) / 10;
		mapa.smazZed(x, y);
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
		g2d.scale(getWidth() / (double) getSirka(), getHeight() / (double) getVyska());
		mapa.kresliMapu(g2d);
	}

	/**
	 * Načte mapu ze souboru na aktuální plochu.
	 *
	 * @return Název načtené mapy.
	 */
	public String nactiMapu() {
		JFileChooser fc = new JFileChooser();
		fc.addChoosableFileFilter(new FileNameExtensionFilter("Soubory s příponou *.ser", "ser"));
		fc.setCurrentDirectory(new File(Mapa.getPath()));
		String zobrazenyNazevMapy = null;
		if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
			zobrazenyNazevMapy = fc.getSelectedFile().getName().substring(0, fc.getSelectedFile().getName().length() - 4);
			try {
				mapa.nactiMapu(zobrazenyNazevMapy, new FileInputStream(fc.getSelectedFile()));
			} catch (FileNotFoundException ex) {
				JOptionPane.showMessageDialog(null, "Zvolený soubor neexistuje.", "Chyba", JOptionPane.ERROR_MESSAGE);
			}
		}
		return zobrazenyNazevMapy;
	}

	/**
	 * Uloží aktuální mapu z plochy do souboru.
	 */
	public void ulozMapu() {
		String nazevMapy = JOptionPane.showInputDialog(this, "Zadejte název mapy", "ULOŽENÍ MAPY", JOptionPane.QUESTION_MESSAGE);
		if (nazevMapy != null) {
			boolean uspech = mapa.ulozMapu(nazevMapy);
			if (uspech) {
				JOptionPane.showMessageDialog(this, "Mapa byla úspěšně uložena do souboru " + nazevMapy + ".ser", "Úspěch", JOptionPane.INFORMATION_MESSAGE);
			} else {
				JOptionPane.showMessageDialog(this, "Mapu se nepodařilo uložit.", "Chyba", JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	/**
	 * Smaže aktuální mapu z plochy.
	 */
	public void smazMapu() {
		Object[] options = { "Ano", "Ne" };
		int vyber = JOptionPane.showOptionDialog(null, "Opravdu chcete smazat tuto mapu?", "Upozornění", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
		if (vyber != 0) {
			return;
		}
		mapa.smazCelouMapu();
	}
}
